﻿using System.Text;
using System.Web;
using System.Collections.Generic;
using Com.FastSearch.SharePoint.WebControls.ESPSearchWebParts.UI;
using Com.FastSearch.SharePoint.WebControls.ESPSearchWebParts.UI.Client;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace ESPWebPartsUnitTest
{
    /// <summary>
    /// Summary description for SearchRequestTest
    /// </summary>
    [TestClass]
    public class SearchRequestTest
    {
        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Use TestInitialize to run code before running each test
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // Use TestCleanup to run code after each test has run
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //
        #endregion


        /// <summary>
        /// Test the parameters with default group
        /// </summary>
        [TestMethod]
        public void DefaultGroupParameterTest()
        {
            ParameterTest(ESPSearchGroupEnum.Group0);
        }

        /// <summary>
        /// Test the parameters with custm search group
        /// </summary>
        [TestMethod]
        public void SearchGroup1ParameterTest()
        {
            ParameterTest(ESPSearchGroupEnum.Group1);
        }

        public void ParameterTest(ESPSearchGroupEnum group)
        {
            HttpRequest httprequest = new HttpRequest("test.aspx", "http://test.com/test.aspx", GetTestQueryParameter(group));

            HttpResponse resp = new HttpResponse(null);
            HttpContext.Current = new HttpContext(httprequest, resp);
            SearchRequest searchRequest = new SearchRequest(group, httprequest);
            if (group != ESPSearchGroupEnum.Group0)
            {
                searchRequest.QueryURLPropertyName = "k" + SearchRequest.GetPropertyPostfixForGroup(group);
            }
            searchRequest.NumberOfResultsPerPage = 10;
            searchRequest.ESPSearchView = "espsystemwebcluster";

            AssertSearchRequestParameter(searchRequest.QueryURLPropertyName, "k" + SearchRequest.GetPropertyPostfixForGroup(group), "QueryURLPropertyName");
            AssertSearchRequestParameter(searchRequest.UserQuery, "test", "k");
            AssertSearchRequestParameter(searchRequest.NumberOfResultsPerPage, 10, "NumberOfResultsPerPage");
            AssertSearchRequestParameter(searchRequest.ESPSearchView, "espsystemwebcluster", "ESPSearchView");

            AssertSearchRequestParameter(searchRequest.Start1, 0, "Start1");
            AssertSearchRequestParameter(searchRequest.LemmatizationEnabled, "false", "LemmatizationEnabled");
            AssertSearchRequestParameter(searchRequest.SynonymsEnabled, "false", "SynonymsEnabled");
            AssertSearchRequestParameter(searchRequest.ResultSorting, null, "%2Dsize");
            AssertSearchRequestParameter(searchRequest.Spellcheck, "false", "Spellcheck");
        }

        /// <summary>
        /// Test the parameters with custm search group
        /// </summary>
        [TestMethod]
        public void CustomParameterGroup0Test()
        {
            CustomParameterTest(ESPSearchGroupEnum.Group0);
        }

        /// <summary>
        /// Test the parameters with custm search group
        /// </summary>
        [TestMethod]
        public void CustomParameterGroup2Test()
        {
            CustomParameterTest(ESPSearchGroupEnum.Group2);
        }

        /// <summary>
        /// Test the parameters with custm search group
        /// </summary>
        [TestMethod]
        public void CustomParameterFailGroup0Test()
        {
            CustomParameterFailTest(ESPSearchGroupEnum.Group0);
        }

        public void CustomParameterTest(ESPSearchGroupEnum group)
        {
            HttpRequest httprequest = new HttpRequest("test.aspx", "http://test.com/test.aspx", GetTestQueryParameter(group));

            HttpResponse resp = new HttpResponse(null);
            HttpContext.Current = new HttpContext(httprequest, resp);
            SearchRequest searchRequest = new SearchRequest(group, httprequest);
            if (group != ESPSearchGroupEnum.Group0)
            {
                searchRequest.QueryURLPropertyName = "k" + SearchRequest.GetPropertyPostfixForGroup(group);
            }
            // Fill in a wired value into the context which is NOT a string as key to test if the
            // GetAllCustomParameter still works in that case....
            HttpContext.Current.Items.Add(true, true);

            searchRequest.SetCustomParameterByName("MySearchParameter1", "MySearchValue1");
            searchRequest.SetCustomParameterByName("MySearchParameter2", "MySearchValue2");

            string resu = searchRequest.GetCustomParameterByName("MySearchParameter1");
            Assert.AreEqual("MySearchValue1", resu);

            resu = searchRequest.GetCustomParameterByName("MySearchParameter2");
            Assert.AreEqual("MySearchValue2", resu);

            resu = searchRequest.GetCustomParameterByName("MySearchParameter3");
            Assert.IsNull(resu);


            List<KeyValuePair<string, string>> resList = searchRequest.GetAllCustomParameter();            
            Assert.AreEqual(2, resList.Count);

            Assert.IsTrue(resList.Contains(new KeyValuePair<string, string>("MySearchParameter1", "MySearchValue1")));
            Assert.IsTrue(resList.Contains(new KeyValuePair<string, string>("MySearchParameter2", "MySearchValue2")));
        }

        public void CustomParameterFailTest(ESPSearchGroupEnum group)
        {
            HttpRequest httprequest = new HttpRequest("test.aspx", "http://test.com/test.aspx", GetTestQueryParameter(group));

            HttpResponse resp = new HttpResponse(null);
            HttpContext.Current = new HttpContext(httprequest, resp);
            SearchRequest searchRequest = new SearchRequest(group, httprequest);
            if (group != ESPSearchGroupEnum.Group0)
            {
                searchRequest.QueryURLPropertyName = "k" + SearchRequest.GetPropertyPostfixForGroup(group);
            }

            bool failed = false;
            try
            {
                searchRequest.SetCustomParameterByName(null, "MySearchValue1");
            }
            catch (SearchRequestParameterException)
            {
                failed = true;
            }
            Assert.IsTrue(failed);

            failed = false;
            try
            {
                searchRequest.SetCustomParameterByName("", "MySearchValue1");
            }
            catch (SearchRequestParameterException)
            {
                failed = true;
            }
            Assert.IsTrue(failed);           

        }


        private string GetTestQueryParameter(ESPSearchGroupEnum group)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append(GetStringValueForGroup(group, "k", "test"));

            return sb.ToString();
        }

        private static string GetStringValueForGroup(ESPSearchGroupEnum group, string key, string value)
        {
            return key + SearchRequest.GetPropertyPostfixForGroup(group) + "=" + value;
        }

        private static void AssertSearchRequestParameter(string value, string expected, string paramName)
        {
            Assert.AreEqual(expected, value, "SearchRequest parameter for Parameter "+ paramName +" does not match!");
        }

        private static void AssertSearchRequestParameter(int value, int expected, string paramName)
        {
            Assert.AreEqual(expected, value, "SearchRequest parameter for Parameter " + paramName + " does not match!");
        }
    }
}